package com.codeduck.guava.collections;

import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;

/**
 * 新 collection 类型: 适用于 JDK 集合无法解决的用例：多重集、多重映射、表、双向映射等。
 * - Guava 引入了许多新的集合类型，它们不在 JDK 中，但我们发现它们非常有用。
 *   这些都是为了与 JDK 集合框架愉快地共存而设计的，而不是硬塞进 JDK 集合抽象中。
 * - 作为一般规则，Guava 集合实现非常精确地遵循 JDK 接口契约。
 * - 参考：https://github.com/google/guava/wiki/NewCollectionTypesExplained
 *
 * @author: <a href="mailto:codeduck@163.com">Codeduck</a>
 * @createDate: 2022-05-19
 */
public class Demo02 {
    public static void main(String[] args) {
        /**
         * 1. Multiset
         * 提供了一种新的集合类型 Multiset，它支持添加多个元素。维基百科在数学中将多集定义为“集合概念的推广，其中成员允许出现不止一次.
         * 在多集中，如集合中，与元组相比，元素的顺序是无关的: 多集{ a，a，b }和{ a，b，a }是相等的。
         *
         * - HashMap 对应 HashMultiset 支持 null 元素
         * - TreeMap 对应 TreeMultiset 支持 null 元素
         * - LinkedHashMap 对应 LinkedHashMultiset 支持 null元素
         * - ConcurrentHashMap 对应 ConcurrentHashMultiset 不支持 null 元素
         * - ImmutableMap 对应 ImmutableMultiset 不支持 null 元素
         */

        /**
         * 2. Multimap
         * 每个经验丰富的 Java 程序员都曾在某个时刻实现过 Map < k，List < v > 或 Map < k，Set < v > ，
         * 并处理过这种结构的笨拙。例如，Map < k，Set < v > 是表示无标记有向图的典型方法。
         * Guava 的 Multimap 框架可以轻松处理从键到多个值的映射。Multimap 是将键与任意多个值相关联的一种通用方法。
         *
         * 从概念上看，有两种方式可以将 Multimap 看作是从单个键到单个值的映射集合:
         * a -> 1
         * a -> 2
         * a -> 4
         * b -> 3
         * c -> 5
         *
         * 或者作为从唯一键到值集合的映射:
         * a -> [1, 2, 4]
         * b -> [3]
         * c -> [5]
         */
        // 创建 Multimap 最直接的方法是使用 MultimapBuilder，它允许您配置应该如何表示键和值。例如:
        ListMultimap<String, Integer> treeListMultimap = MultimapBuilder.treeKeys().arrayListValues().build();
        // 您也可以选择直接在实现类上使用 create ()方法，但是对于 multiapbuilder 来说，稍微不鼓励这样做。

        /**
         * 3. BiMap
         */
        /**
         * 4. Table
         */
        /**
         * 5. ClassTonInstanceMap
         */
        /**
         * 6. RangeSet
         */

        /**
         * 7. RangeMap
         */
    }
}
